package br.com.educa.modelo.financeiro;

import br.com.educa.modelo.academico.Alunos;
import br.com.educa.modelo.academico.AlunosTurmas;
import br.com.educa.modelo.academico.Turmas;
import br.com.educa.modelo.financeiro.enumerator.SituacaoLancamentoAluno;
import br.com.educa.modelo.publico.Controle;
import flexjson.JSONDeserializer;
import flexjson.JSONSerializer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.PersistenceContext;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;
import org.springframework.roo.addon.json.RooJson;
import org.springframework.roo.addon.serializable.RooSerializable;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.transaction.annotation.Transactional;

@Entity
@Table
@Configurable
@RooJson
@RooSerializable
@RooJavaBean
@RooToString
@RooJpaActiveRecord(finders = { "findLancamentosAlunosesByAluno" })
public class LancamentosAlunos implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;
    
    @ManyToOne
    @JoinColumn(name = "controle", referencedColumnName = "id")
    private Controle controle;

    @ManyToOne
    @JoinColumn(name = "aluno", referencedColumnName = "id")
    private Alunos aluno;
    
    @ManyToOne
    @JoinColumn(name = "negociacao", referencedColumnName = "id")
    private Negociacoes negociacao;

    @ManyToOne
    @JoinColumn(name = "historico", referencedColumnName = "id")
    private Historicos historico;

    @Temporal(TemporalType.DATE)
    @DateTimeFormat(style = "M-")
    private Date dataRegistro;

    @Temporal(TemporalType.DATE)
    @DateTimeFormat(style = "M-")
    private Date dataVencimento;

    @NotNull
    private Double valorBase;

    @Enumerated(EnumType.STRING)
    private SituacaoLancamentoAluno situacaoLancamento;

    private Double desconto;

    private String observacao;

    private Double valorPago;

    @Temporal(TemporalType.DATE)
    @DateTimeFormat(style = "M-")
    private Date dataPagamento;

    private Double multa;
    
    private Boolean isento = false;

    private static final long serialVersionUID = 1L;

    @PersistenceContext
    transient EntityManager entityManager;

    public String toJson() {
        return new JSONSerializer().exclude("*.class").serialize(this);
    }

    public static br.com.educa.modelo.financeiro.LancamentosAlunos fromJsonToLancamentosAlunos(String json) {
        return new JSONDeserializer<LancamentosAlunos>().use(null, LancamentosAlunos.class).deserialize(json);
    }

    public static String toJsonArray(Collection<br.com.educa.modelo.financeiro.LancamentosAlunos> collection) {
        return new JSONSerializer().exclude("*.class").serialize(collection);
    }

    public static Collection<br.com.educa.modelo.financeiro.LancamentosAlunos> fromJsonArrayToLancamentosAlunoses(String json) {
        return new JSONDeserializer<List<LancamentosAlunos>>().use(null, ArrayList.class).use("values", LancamentosAlunos.class).deserialize(json);
    }

    public static final EntityManager entityManager() {
        EntityManager em = new LancamentosAlunos().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

    public static long countLancamentosAlunoses() {
        return entityManager().createQuery("SELECT COUNT(o) FROM LancamentosAlunos o", Long.class).getSingleResult();
    }

    public static List<br.com.educa.modelo.financeiro.LancamentosAlunos> findAllLancamentosAlunoses() {
        return entityManager().createQuery("SELECT o FROM LancamentosAlunos o", LancamentosAlunos.class).getResultList();
    }

    public static br.com.educa.modelo.financeiro.LancamentosAlunos findLancamentosAlunos(Long id) {
        if (id == null) return null;
        return entityManager().find(LancamentosAlunos.class, id);
    }

    public static List<br.com.educa.modelo.financeiro.LancamentosAlunos> findLancamentosAlunosEntries(int firstResult, int maxResults) {
        return entityManager().createQuery("SELECT o FROM LancamentosAlunos o", LancamentosAlunos.class).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
    }

    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.persist(this);
    }

    @Transactional
    public void remove() {
        if (this.entityManager == null) this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            LancamentosAlunos attached = LancamentosAlunos.findLancamentosAlunos(this.id);
            this.entityManager.remove(attached);
        }
    }

    @Transactional
    public void flush() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.flush();
    }

    @Transactional
    public void clear() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.clear();
    }

    @Transactional
    public br.com.educa.modelo.financeiro.LancamentosAlunos merge() {
        if (this.entityManager == null) this.entityManager = entityManager();
        LancamentosAlunos merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getVersion() {
        return this.version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public Alunos getAluno() {
        return this.aluno;
    }

    public void setAluno(Alunos aluno) {
        this.aluno = aluno;
    }

    public String toString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

    public Historicos getHistorico() {
        return this.historico;
    }

    public void setHistorico(Historicos historico) {
        this.historico = historico;
    }

    public Date getDataRegistro() {
        return this.dataRegistro;
    }

    public void setDataRegistro(Date dataRegistro) {
        this.dataRegistro = dataRegistro;
    }

    public Date getDataVencimento() {
        return this.dataVencimento;
    }

    public void setDataVencimento(Date dataVencimento) {
        this.dataVencimento = dataVencimento;
    }

    public Double getValorBase() {
        return this.valorBase;
    }

    public void setValorBase(Double valorBase) {
        this.valorBase = valorBase;
    }

    public SituacaoLancamentoAluno getSituacaoLancamento() {
        return this.situacaoLancamento;
    }

    public void setSituacaoLancamento(SituacaoLancamentoAluno situacaoLancamento) {
        this.situacaoLancamento = situacaoLancamento;
    }

    public Double getDesconto() {
        return this.desconto;
    }

    public void setDesconto(Double desconto) {
        this.desconto = desconto;
    }

    public String getObservacao() {
        return this.observacao;
    }

    public void setObservacao(String observacao) {
        this.observacao = observacao;
    }

    public Double getValorPago() {
        return this.valorPago;
    }

    public void setValorPago(Double valorPago) {
        this.valorPago = valorPago;
    }

    public Date getDataPagamento() {
        return this.dataPagamento;
    }

    public void setDataPagamento(Date dataPagamento) {
        this.dataPagamento = dataPagamento;
    }

    public Double getMulta() {
        return this.multa;
    }

    public void setMulta(Double multa) {
        this.multa = multa;
    }

	public static TypedQuery<LancamentosAlunos> findLancamentosAlunosesByAluno(Alunos aluno) {
        if (aluno == null) throw new IllegalArgumentException("The aluno argument is required");
        EntityManager em = LancamentosAlunos.entityManager();
        TypedQuery<LancamentosAlunos> q = em.createQuery("SELECT o FROM LancamentosAlunos AS o WHERE o.aluno = :aluno", LancamentosAlunos.class);
        q.setParameter("aluno", aluno);
        return q;
    }
	
	public static TypedQuery<LancamentosAlunos> findLancamentosAlunosesByAlunoAberto(Alunos aluno) {
        if (aluno == null) throw new IllegalArgumentException("The aluno argument is required");
        EntityManager em = LancamentosAlunos.entityManager();
        TypedQuery<LancamentosAlunos> q = em.createQuery("SELECT o FROM LancamentosAlunos AS o WHERE o.aluno = :aluno AND situacaoLancamento LIKE 'Aberta' order by dataVencimento", LancamentosAlunos.class);
        q.setParameter("aluno", aluno);
        return q;
    }
//	
//	public static TypedQuery<LancamentosAlunos> findLancamentosAlunosesByAlunoTurma(Alunos aluno, Turmas turma) {
//        if (aluno == null) throw new IllegalArgumentException("The aluno argument is required");
//        EntityManager em = LancamentosAlunos.entityManager();
//        TypedQuery<LancamentosAlunos> q = em.createQuery("SELECT o FROM LancamentosAlunos AS o WHERE o.aluno = :aluno AND situacaoLancamento LIKE 'Aberta'", LancamentosAlunos.class);
//        q.setParameter("aluno", aluno);
//        q.setParameter("turma", turma);
//        return q;
//    }
	

	public Negociacoes getNegociacao() {
        return this.negociacao;
    }

	public void setNegociacao(Negociacoes negociacao) {
        this.negociacao = negociacao;
    }

	public Boolean getIsento() {
        return this.isento;
    }

	public void setIsento(Boolean isento) {
        this.isento = isento;
    }

	public Controle getControle() {
        return this.controle;
    }

	public void setControle(Controle controle) {
        this.controle = controle;
    }
}
